.TH std::variant 3 "2024.06.10" "http://cppreference.com" "C++ Standard Libary"
.SH NAME
std::variant \- std::variant

.SH Synopsis
   Defined in header <variant>
   template< class... Types >   \fI(since C++17)\fP
   class variant;

   The class template std::variant represents a type-safe union. An instance of
   std::variant at any given time either holds a value of one of its alternative types,
   or in the case of error - no value (this state is hard to achieve, see
   valueless_by_exception).

   As with unions, if a variant holds a value of some object type T, the object
   representation of T is allocated directly within the object representation of the
   variant itself. Variant is not allowed to allocate additional (dynamic) memory.

   A variant is not permitted to hold references, arrays, or the type void.

   A variant is permitted to hold the same type more than once, and to hold differently
   cv-qualified versions of the same type.

   Consistent with the behavior of unions during aggregate initialization, a
   default-constructed variant holds a value of its first alternative, unless that
   alternative is not default-constructible (in which case the variant is not
   default-constructible either). The helper class std::monostate can be used to make
   such variants default-constructible.

   A program that instantiates the definition of std::variant with no template
   arguments is ill-formed. std::variant<std::monostate> can be used instead.

   If a program declares an explicit or partial specialization of std::variant, the
   program is ill-formed, no diagnostic required.

.SH Template parameters

           the types that may be stored in this variant. All types must meet the
   Types - Destructible requirements (in particular, array types and non-object types
           are not allowed).

.SH Member functions

   constructor            constructs the variant object
                          \fI(public member function)\fP
   destructor             destroys the variant, along with its contained value
                          \fI(public member function)\fP
   operator=              assigns a variant
                          \fI(public member function)\fP
.SH Observers
                          returns the zero-based index of the alternative held by the
   index                  variant
                          \fI(public member function)\fP
   valueless_by_exception checks if the variant is in the invalid state
                          \fI(public member function)\fP
.SH Modifiers
   emplace                constructs a value in the variant, in place
                          \fI(public member function)\fP
   swap                   swaps with another variant
                          \fI(public member function)\fP
         Visitation
   visit                  calls the provided functor with the argument held by the
   (C++26)                variant
                          \fI(public member function)\fP

.SH Non-member functions

   visit                   calls the provided functor with the arguments held by one or
   \fI(C++17)\fP                 more variants
                           \fI(function template)\fP
   holds_alternative       checks if a variant currently holds a given type
   \fI(C++17)\fP                 \fI(function template)\fP
   get(std::variant)       reads the value of the variant given the index or the type
   \fI(C++17)\fP                 (if the type is unique), throws on error
                           \fI(function template)\fP
   get_if                  obtains a pointer to the value of a pointed-to variant given
   \fI(C++17)\fP                 the index or the type (if unique), returns null on error
                           \fI(function template)\fP
   operator==
   operator!=
   operator<
   operator<=
   operator>
   operator>=
   operator<=>             compares variant objects as their contained values
   \fI(C++17)\fP                 \fI(function template)\fP
   \fI(C++17)\fP
   \fI(C++17)\fP
   \fI(C++17)\fP
   \fI(C++17)\fP
   \fI(C++17)\fP
   (C++20)
   std::swap(std::variant) specializes the std::swap algorithm
   \fI(C++17)\fP                 \fI(function template)\fP

.SH Helper classes

   monostate               placeholder type for use as the first alternative in a
   \fI(C++17)\fP                 variant of non-default-constructible types
                           \fI(class)\fP
   bad_variant_access      exception thrown on invalid accesses to the value of a
   \fI(C++17)\fP                 variant
                           \fI(class)\fP
   variant_size            obtains the size of the variant's list of alternatives at
   variant_size_v          compile time
   \fI(C++17)\fP                 \fI(class template)\fP (variable template)
   variant_alternative     obtains the type of the alternative specified by its index,
   variant_alternative_t   at compile time
   \fI(C++17)\fP                 \fI(class template)\fP (alias template)
   std::hash<std::variant> hash support for std::variant
   \fI(C++17)\fP                 \fI(class template specialization)\fP

   Helper objects

   variant_npos index of the variant in the invalid state
   \fI(C++17)\fP      (constant)

.SH Notes

   Feature-test macro  Value    Std                       Feature
                      201606L \fI(C++17)\fP std::variant: a type-safe union
                      202102L \fI(C++17)\fP std::visit for classes derived from std::variant
   __cpp_lib_variant          (DR)
                      202106L (C++20) Fully constexpr std::variant
                              (DR)
                      202306L (C++26) Member visit

.SH Example


// Run this code

 #include <cassert>
 #include <iostream>
 #include <string>
 #include <variant>

 int main()
 {
     std::variant<int, float> v, w;
     v = 42; // v contains int
     int i = std::get<int>(v);
     assert(42 == i); // succeeds
     w = std::get<int>(v);
     w = std::get<0>(v); // same effect as the previous line
     w = v; // same effect as the previous line

 //  std::get<double>(v); // error: no double in [int, float]
 //  std::get<3>(v);      // error: valid index values are 0 and 1

     try
     {
         std::get<float>(w); // w contains int, not float: will throw
     }
     catch (const std::bad_variant_access& ex)
     {
         std::cout << ex.what() << '\\n';
     }

     using namespace std::literals;

     std::variant<std::string> x("abc");
     // converting constructors work when unambiguous
     x = "def"; // converting assignment also works when unambiguous

     std::variant<std::string, void const*> y("abc");
     // casts to void const * when passed a char const *
     assert(std::holds_alternative<void const*>(y)); // succeeds
     y = "xyz"s;
     assert(std::holds_alternative<std::string>(y)); // succeeds
 }

.SH Possible output:

 std::get: wrong index for variant

   Defect reports

   The following behavior-changing defect reports were applied retroactively to
   previously published C++ standards.

      DR    Applied to         Behavior as published              Correct behavior
                       specialization of std::uses_allocator
   LWG 2901 C++17      provided,                              specialization removed
                       but std::variant cannot properly
                       support allocators
                                                              the program is ill-formed
   LWG 3990 C++17      a program could declare an explicit or in this
                       partial specialization of std::variant case (no diagnostic
                                                              required)

.SH See also

   in_place
   in_place_type
   in_place_index   in-place construction tag
   in_place_t       (tag)
   in_place_type_t
   in_place_index_t
   \fI(C++17)\fP
   optional         a wrapper that may or may not hold an object
   \fI(C++17)\fP          \fI(class template)\fP
   any              objects that hold instances of any CopyConstructible type
   \fI(C++17)\fP          \fI(class)\fP
